Skip to content

Route unmatched H264 formats to platform decoder factories - #1312

Closed
MaxHeimbrock wants to merge 1 commit into
mainfrom
max/relax-h264codec-constraints
Closed

Route unmatched H264 formats to platform decoder factories#1312
MaxHeimbrock wants to merge 1 commit into
mainfrom
max/relax-h264codec-constraints

Conversation

@MaxHeimbrock

@MaxHeimbrock MaxHeimbrock commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

The SFU now includes H.264 Baseline (42001f) in its default codec set and selects the forwarded codec from the subscriber's SDP. Create() matched platform factories with IsSameCodec, which is strict on profile-level-id; VideoToolbox only advertises 42e01f/640c1f, so 42001f fell through to the internal FFmpeg decoder, which desktop prebuilts cannot initialize (no H.264 codec compiled in) — every frame failed to decode and subscribers saw black video in a PLI loop.

Hardware decoders handle Baseline/Main/High regardless of the exact fmtp they advertise, so when no exact or packetization-mode-relaxed match exists, create the decoder from the platform factory's own advertised H.264 format instead of falling through.

Solving issue description client side

The SFU now includes H.264 Baseline (42001f) in its default codec set
and selects the forwarded codec from the subscriber's SDP. Create()
matched platform factories with IsSameCodec, which is strict on
profile-level-id; VideoToolbox only advertises 42e01f/640c1f, so
42001f fell through to the internal FFmpeg decoder, which desktop
prebuilts cannot initialize (no H.264 codec compiled in) — every
frame failed to decode and subscribers saw black video in a PLI loop.

Hardware decoders handle Baseline/Main/High regardless of the exact
fmtp they advertise, so when no exact or packetization-mode-relaxed
match exists, create the decoder from the platform factory's own
advertised H.264 format instead of falling through.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

No changeset found

This PR modifies versioned packages but doesn't include a changeset. The following packages require a version bump:

  • libwebrtc
  • livekit
  • livekit-ffi
  • webrtc-sys

A package must be bumped when its own files change, and whenever a package it depends on is bumped (so downstream consumers get a matching release).

Click here to create a changeset for the missing packages

The link pre-populates a changeset file with patch bumps for the missing packages. You can also add them to your existing changeset. Edit the bump types as needed before committing.

If this change doesn't require a version bump, add the internal label to this PR.

@MaxHeimbrock

Copy link
Copy Markdown
Contributor Author

From more digging:

The theoretical bad combination. The new fallback sits above the internal webrtc::H264Decoder::Create() path in Create(). So any H.264 format that doesn't strictly match a platform factory now goes to the platform factory — the internal decoder is never consulted for H.264 again on platforms that have one.

That's harmless today because the internal decoder is broken on every desktop prebuilt (that's the bug). But picture a build where FFmpeg H.264 actually works (Option C, or some future prebuilt): Fix B's probe passes, so we advertise the internal list — which includes High 4:4:4 Predictive.

If such a stream arrived, strict match against VideoToolbox fails, the fallback fires, and VideoToolbox gets a 4:4:4 stream it very likely can't decode — while a working FFmpeg sits unused. That's the one case where A regresses relative to no-A, and it requires a working internal decoder plus an exotic profile, neither of which exists in current desktop builds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant